From a4ba25f0f8e081ae763096c5b1d5842a072d6695 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 5 Sep 2020 22:35:30 -0400 Subject: [PATCH] inspector: Fix teardown of the general tab We were connecting signal handlers to the display and seats here, and never cleaning them up, leading to crashes after the inspector is closed. This is fairly easy to reproduce under Wayland, where the scroll device is only created the first time we create a scroll event. --- gtk/inspector/general.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/gtk/inspector/general.c b/gtk/inspector/general.c index 76bd0011e2..ab368e2f8d 100644 --- a/gtk/inspector/general.c +++ b/gtk/inspector/general.c @@ -817,6 +817,13 @@ add_seat (GtkInspectorGeneral *gen, g_list_free (list); } +static void +disconnect_seat (GtkInspectorGeneral *gen, + GdkSeat *seat) +{ + g_signal_handlers_disconnect_by_func (seat, G_CALLBACK (populate_seats), gen); +} + static void populate_seats (GtkInspectorGeneral *gen) { @@ -835,11 +842,28 @@ populate_seats (GtkInspectorGeneral *gen) g_list_free (list); } +static void +seat_added (GdkDisplay *display, + GdkSeat *seat, + GtkInspectorGeneral *gen) +{ + populate_seats (gen); +} + +static void +seat_removed (GdkDisplay *display, + GdkSeat *seat, + GtkInspectorGeneral *gen) +{ + disconnect_seat (gen, seat); + populate_seats (gen); +} + static void init_device (GtkInspectorGeneral *gen) { - g_signal_connect_swapped (gen->display, "seat-added", G_CALLBACK (populate_seats), gen); - g_signal_connect_swapped (gen->display, "seat-removed", G_CALLBACK (populate_seats), gen); + g_signal_connect (gen->display, "seat-added", G_CALLBACK (seat_added), gen); + g_signal_connect (gen->display, "seat-removed", G_CALLBACK (seat_removed), gen); populate_seats (gen); } @@ -911,9 +935,18 @@ static void gtk_inspector_general_dispose (GObject *object) { GtkInspectorGeneral *gen = GTK_INSPECTOR_GENERAL (object); + GList *list, *l; g_clear_pointer (&gen->swin, gtk_widget_unparent); + g_signal_handlers_disconnect_by_func (gen->display, G_CALLBACK (seat_added), gen); + g_signal_handlers_disconnect_by_func (gen->display, G_CALLBACK (seat_removed), gen); + + list = gdk_display_list_seats (gen->display); + for (l = list; l; l = l->next) + disconnect_seat (gen, GDK_SEAT (l->data)); + g_list_free (list); + G_OBJECT_CLASS (gtk_inspector_general_parent_class)->dispose (object); } -- 2.30.2